package editor.logic;

import moltencore.game.loader.Level;
import moltencore.game.loader.LevelLoader;
import moltencore.game.loader.LevelSprite;
import spark.math.Vector2;
import spark.exception.LoadingException;
import moltencore.game.bubble.Type;
import moltencore.game.collision.VerticalLine;
import moltencore.game.collision.HorizontalLine;

import java.io.FileOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

public class Editor {
	public static final float GEOMETRY_DEPTH = -.001f;
	public static final float BUBBLE_DEPTH = 0f;
	public static final float OTHER_DEPTH = -0.005f;
	public static final float WALL_DEPTH = 0.009f;
	public static final float FRONT_DEPTH = 0.1f;
	private Level level;

	public void newLevel() {
		level = new Level();
	}

	public String getLevelName() {
		return level.getName() + Level.EXTENSION;
	}

	public void setLevelName(String name) {
		level.setName(name);
	}

	public void stamp(LevelSprite levelSprite) {
		levelSprite.getRenderable().getPosition().z = GEOMETRY_DEPTH;
		level.addSprite(levelSprite);
	}

	public void addBubble(Type type, int gridPositionX, int gridPositionY) {
		level.addBubble(type, gridPositionX, gridPositionY);
	}

	public void addPush(int gridPositionX, int gridPositionY) {
		level.addPushBubble(gridPositionX, gridPositionY);
	}

	public void addFill(int gridPositionX, int gridPositionY) {
		level.addFillBubble(gridPositionX, gridPositionY);
	}

	public void setResult(float x, float y) {
		level.setResultPosition(new Vector2(x, y));
	}

	public void setScore(float x, float y) {
		level.setScorePosition(new Vector2(x, y));
	}

	public void setCannonPosition(Vector2 position, int index) {
		level.setCannonPosition(position, index);
	}

	public void setCannonNextPosition(Vector2 position, int index) {
		level.setCannonNextPosition(position, index);
	}

	public void setCannonTarget(Vector2 target, int index) {
		level.setCannonTarget(target, index);
	}

	public void setClock(float x, float y) {
		level.setClockPosition(new Vector2(x, y));
	}

	public void setNick(float x, float y) {
		level.setNickPosition(new Vector2(x, y));
	}

	public Level getCurrentlevel() {
		return level;
	}

	public void makeHorizontalWall(float y) {
		level.add(new HorizontalLine(y, true));
	}

	public void makeVerticalWall(float x) {
		level.add(new VerticalLine(x, false));
	}

	public void makeRestrictedArea(float y) {
		level.addRestrictedArea(new HorizontalLine(y, false));
	}

	public void makeCriticalArea(float y) {
		level.addCriticalArea(new HorizontalLine(y, false));
	}

	public void makeKillArea(float y) {
		level.addKillArea(new HorizontalLine(y, false));
	}

	public void save(File destination) throws LoadingException {
		LevelSaver saver = new LevelSaver();
		if(!destination.getPath().endsWith("." + Level.EXTENSION) &&
		   !destination.getPath().contains(".")) {
			destination = new File(destination.getPath() + "." + Level.EXTENSION);
		}
		try {
			if(!destination.exists()) {
				//noinspection ResultOfMethodCallIgnored
				destination.createNewFile();
			}
			saver.save(level, new FileOutputStream(destination));
		}
		catch(FileNotFoundException e) {
			throw new AssertionError(e);
		}
		catch(IOException e) {
			throw new LoadingException(e);
		}
	}

	public void open(File selectedFile) throws LoadingException {
		LevelLoader loader = new LevelLoader();
		level = loader.loadLevel(selectedFile.getAbsolutePath(), new LevelParser2());
	}
}
